package com.allen.app.common.utils;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import java.io.IOException;
import java.io.Reader;
import java.util.Map;
import java.util.Objects;

/**
 * 基于jackson的JSON转换工具类。必须引入一下jar： <p>jackson-module-parameter-names.jar </p> <p>jackson-datatype-jdk8.jar </p>
 * <p>jackson-datatype-jsr310.jar </p>
 *
 * @author leon created by 2017-12-05 22:04:12.336
 */
public class Jackson {

    private static final ObjectMapper mapper = new ObjectMapper()
        .disable(SerializationFeature.FAIL_ON_EMPTY_BEANS)
        .configure(MapperFeature.DEFAULT_VIEW_INCLUSION, false)
        .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
        .findAndRegisterModules();



    public static String json(Object object) {
        if (Objects.isNull(object)) {
            return StrUtil.EMPTY;
        }
        return Try.unchecked(() -> mapper.writeValueAsString(object));
    }

    public static JSONObject jsonObject(Object object) {
        if (Objects.isNull(object)) {
            return new JSONObject();
        }

        return Try.unchecked(() -> object(object, JSONObject.class));
    }

    public static <T> T object(Reader json, Class<T> type) {
        if (Objects.isNull(json)) {
            return null;
        }
        return Try.unchecked(() -> mapper.readValue(json, type));
    }

    public static <T> T object(Object object, Class<T> type) {
        if (Objects.isNull(object)) {
            return null;
        }
        String jsonStr = "";
        if(object instanceof String){
            jsonStr = Convert.toStr(object);
        }else{
            jsonStr = json(object);
        }

        String finalJsonStr = jsonStr;
        return Try.unchecked(() -> mapper.readValue(finalJsonStr, type));
    }

    /**
     * 泛型转换:调用方式 object(json,new TypeReference<List<User>>() {})
     * @param object json对象
     * @param typeReference 泛型对象
     * @return <T> 返回对象
     */
    public static <T> T object(Object object,TypeReference<?> typeReference){
        if (Objects.isNull(object)) {
            return null;
        }
        String jsonStr = "";
        if(object instanceof String){
            jsonStr = (String) object;
        }else{
            jsonStr = json(object);
        }

        try {
            //noinspection unchecked
            return (T) mapper.readValue(jsonStr, typeReference);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static Map<String, Object> map(String json) {
        //noinspection unchecked
        return Try.unchecked(() -> Jackson.object(json, Map.class));
    }

//    public static void main(String[] args) {
//        String jsonStr = "{\"a\":1,\"b\":\"狗屁不是\"}";
//        String jsonStrArr = "[{\"a\":1,\"b\":\"狗屁不是\"},{\"a\":1,\"b\":\"狗屁不是\"},{\"a\":1,\"b\":\"狗屁不是\"}]";
//        System.out.println(object(jsonStrArr, JSONArray.class));

//    }

}
